package com.bort.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.bort.system.BortApplication;
import com.bort.system.common.DataContainer;
import com.bort.system.info.DeskInfo;
import com.bort.system.model.Cart;
import com.bort.system.model.TGameLog;
import com.bort.system.serial.SerialManager;
import com.bort.system.service.ClientService;
import com.bort.system.service.impl.ClientServiceImpl;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

public class DeskController implements Initializable {

    Logger logger = LoggerFactory.getLogger(DeskController.class);

    ClientService clientService;

    SerialManager serialManager;

    private static final double WarningValue = 0.95;

    private static final Integer One = 1;

    private boolean endWarning = false;

    @FXML
    ImageView bgView;

    @FXML
    Button playBtn;

    @FXML
    Button stopBtn;

    @FXML
    Button lightBtn;

    @FXML
    Label deskNo;

    @FXML
    Label deskPrice;

    @FXML
    Label descTime;

    @FXML
    Label startTime;

    @FXML
    Label endTime;

    @FXML
    FlowPane progressPane;

    @FXML
    ProgressBar progressBar;

    @FXML
    ImageView cartImgView;

    @FXML
    Label cartGoodsNum;

    Label  progressLabel;

    Timer timer;

    BigDecimal value = new BigDecimal(0);

    protected Image stopBg = null;
    protected Image playBg = null;
    protected Image inactive = null;
    protected Image broken = null;

    protected Image cartOpen = null;
    protected Image cartClose = null;

    protected String sthInCartStyle = "-fx-font-size: 10;-fx-border-color: #000000;-fx-border-radius: 10;-fx-border-width: 1";
    protected String cartEmptyStyle = "-fx-font-size: 10;-fx-border-width: 0";

    protected DeskInfo data;

    private Map<String,String> playBtnStyle = new HashMap<>();
    private Map<String,String> stopBtnStyle = new HashMap<>();
    private Map<String,String> lightBtnStyle = new HashMap<>();

    private boolean deskAvailable = true;

    @FXML
    void onPlayClick(ActionEvent event){
        Integer one = 1;
        DataContainer.selectDeskId = data.getId();
        DataContainer.deskCtrlMap.put(data.getId(),this);
        if(deskAvailable) {
            if ("1".equals(data.getStatus())) {
                openDialog("/view/dialogView.fxml");
            } else if ("2".equals(data.getStatus()) && one.equals(data.getTimeLimit())) {
                openDialog("/view/overtimeDialogView.fxml");
            }
        }
    }

    @FXML
    void onStopClick(ActionEvent event){
        if("2".equals(data.getStatus())) {
            DataContainer.selectDeskId = data.getId();
            DataContainer.deskCtrlMap.put(data.getId(),this);
            Integer one = 1;
            if(one.equals(data.getTimeLimit())){
                openDialog("/view/closeDialog.fxml");
            }else{
                openDialog("/view/closeDialogUnLimit.fxml");
            }
        }
    }

    @FXML
    void onLightPress(){
        if("2".equals(data.getStatus())) {
            lightBtn.setStyle(lightBtnStyle.get("disable"));
        }
    }

    @FXML
    void onLightRelease(){
        if("2".equals(data.getStatus())){
            lightBtn.setStyle(lightBtnStyle.get("enable"));
            lightControl(true);
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        clientService = ClientServiceImpl.getInstance();
        serialManager = SerialManager.getInstance();
        playBg = new Image("img/open.png");
        stopBg = new Image("img/stop.jpg");
        inactive = new Image("img/inactive.png");
        broken = new Image("img/broken.png");
        cartOpen = new Image("img/cart_open.png");
        cartClose = new Image("img/cart_close.png");
        playBtnStyle.put("enable","-fx-background-color: #0facea;-fx-border-color: #BCBCBC;");
        playBtnStyle.put("disable","-fx-background-color: #a9c8dc;-fx-border-color: #BCBCBC");
        stopBtnStyle.put("enable","-fx-background-color: #fa542b;-fx-border-color: #BCBCBC");
        stopBtnStyle.put("disable","-fx-background-color: #DEA6A6;-fx-border-color: #BCBCBC");
        lightBtnStyle.put("enable","-fx-background-color: #FCA032;-fx-border-color: #BCBCBC");
        lightBtnStyle.put("disable","-fx-background-color: #DCB687;-fx-border-color: #BCBCBC");
        bgView.setImage(stopBg);
        data = JSONObject.parseObject(JSONObject.toJSONString(DataContainer.deskContainer.get(DataContainer.deskIndex)),DeskInfo.class);
        initData(null);
        DataContainer.deskCtrlMap.put(data.getId(),this);
        if("2".equals(data.getStatus())){
            lightControl(true);
        }
    }

    private void initData(Integer status) {
        deskAvailable = true;
        deskNo.setText(data.getDeskNo()!=null?data.getDeskNo().toString():"-");
        cartGoodsNum.setStyle(cartEmptyStyle);
        cartGoodsNum.setText(null);
        if("1".equals(data.getStatus())){
            if(endWarning){
                lightControl(false);
                endWarning = false;
            }
            playBtn.setText("开始游戏");
            bgView.setImage(stopBg);
            playBtn.setStyle(playBtnStyle.get("enable"));
            stopBtn.setStyle(stopBtnStyle.get("disable"));
            lightBtn.setStyle(lightBtnStyle.get("disable"));
        }else if("2".equals(data.getStatus())){
            bgView.setImage(playBg);
            if(One.equals(data.getTimeLimit())){
                playBtn.setStyle(playBtnStyle.get("enable"));
                playBtn.setText("加时");
            }else{
                playBtn.setStyle(playBtnStyle.get("disable"));
            }
            stopBtn.setStyle(stopBtnStyle.get("enable"));
            lightBtn.setStyle(lightBtnStyle.get("enable"));
            List<Cart> carts = data.getCartList();
            if(carts != null && carts.size() > 0){
                Integer sum = carts.stream().map(mp -> mp.getNum()).reduce(0,(n1,n2) ->   n1 + n2  );
                if(sum > 0){
                    cartGoodsNum.setStyle(sthInCartStyle);
                    cartGoodsNum.setText(sum.toString());
                }
            }
        }else if("3".equals(data.getStatus())){
            bgView.setImage(broken);
            playBtn.setStyle(playBtnStyle.get("disable"));
            stopBtn.setStyle(stopBtnStyle.get("disable"));
            lightBtn.setStyle(lightBtnStyle.get("disable"));
        }else if("0".equals(data.getStatus())){
            bgView.setImage(inactive);
            playBtn.setStyle(playBtnStyle.get("disable"));
            stopBtn.setStyle(stopBtnStyle.get("disable"));
            lightBtn.setStyle(lightBtnStyle.get("disable"));
        }
        deskPrice.setText(data.getPrice().toString()+"￥");
        data.getStartTime();
        descTime.setText("无");
        startTime.setText("无");
        endTime.setText("无");
        Integer one = 1;
        if("2".equals(data.getStatus())){
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd日 HH:mm");
            if(one.equals(data.getTimeLimit())){
                if (data.getStartTime() != null && data.getEndTime() != null) {
                    long start = data.getStartTime().getTime();
                    long end = data.getEndTime().getTime();
                    long expire = end - start;
                    BigDecimal timeLong = new BigDecimal(expire / 1000).divide(new BigDecimal(3600), 2, BigDecimal.ROUND_HALF_UP);
                    descTime.setText(timeLong.toString());
                    String startStr = dateFormat.format(data.getStartTime());
                    String endStr = dateFormat.format(data.getEndTime());
                    startTime.setText(startStr);
                    endTime.setText(endStr);

                    long now = System.currentTimeMillis();
                    long playLong = now - start;
                    BigDecimal progress = new BigDecimal(playLong/1000).divide(new BigDecimal(expire / 1000), 2, BigDecimal.ROUND_DOWN);
                    progressBar.setProgress(progress.doubleValue());
                    progressBar.setPrefWidth(260.00);
                    BigDecimal value = progress.multiply(new BigDecimal(100));
                    if(value.compareTo(new BigDecimal(100)) > 0){
                        value = new BigDecimal(100.00);
                    }
                    if(progressPane.getChildren().size() >= 2){
                        progressLabel = (Label) progressPane.getChildren().get(1);
                        progressLabel.setText(value.toString()+"%");
                    }else{
                        progressLabel = new Label(value.toString()+"%");
                        progressLabel.setStyle("-fx-padding:0px 0px 0px 4px ");
                        progressPane.getChildren().add(progressLabel);
                    }
                }else if (data.getStartTime() != null) {
                    String startStr = dateFormat.format(data.getStartTime());
                    startTime.setText(startStr);
                    progressBar.setProgress(0.5);
                } else {
                    descTime.setText("无限");
                }
            }else{
                descTime.setText("无限");
                if (data.getStartTime() != null) {
                    String startStr = dateFormat.format(data.getStartTime());
                    startTime.setText(startStr);
                    progressAnimationStart();
                }
                cartImgView.setImage(cartOpen);
            }
        }else {
            progressBar.setProgress(0);
            if(progressPane.getChildren().size() >= 2){
                progressPane.getChildren().remove(1);
            }
            cartImgView.setImage(cartClose);
        }
        if(one.equals(data.getTimeLimit())) {
            if (isGreater(progressBar.getProgress(), WarningValue)) {
                progressBar.setStyle("-fx-accent: #e14848;");
                endWarning = true;
            } else {
                progressBar.setStyle("-fx-accent: #41a0b9;");
            }
        }

        if(null != status && status.equals(5)){
            playBtn.setStyle(playBtnStyle.get("disable"));
            deskAvailable = false;
        }
    }

    private void progressAnimationStart() {
        if(timer == null){
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    value = value.add(new BigDecimal(0.01)).setScale(2,BigDecimal.ROUND_HALF_UP);
                    progressBar.setProgress(value.doubleValue());
                    if(value.compareTo(BigDecimal.ONE) >= 0 ){
                        value = BigDecimal.ZERO;
                    }
                }
            },0,10);
        }
    }

    public static boolean isGreater(double val1, double val2) {
        return (new BigDecimal(val1)).compareTo(new BigDecimal(val2)) > 0;
    }

    private void openDialog(String view) {
        FXMLLoader fxmlLoader = new FXMLLoader(MainAppController.class.getResource(view));
        try {
            Stage stage = new Stage();
            stage.setResizable(false);
            stage.initOwner(BortApplication.getStage());
            stage.initModality(Modality.WINDOW_MODAL);
            stage.initStyle(StageStyle.UTILITY);
            stage.setTitle("开始游戏");
            Scene scene = new Scene(fxmlLoader.load());
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void deskOpen(TGameLog gameLog){
        bgView.setImage(playBg);
        data.setLogId(gameLog.getId());
        data.setStatus(gameLog.getStatus());
        data.setStartTime(gameLog.getCreateTime());
        data.setEndTime(gameLog.getEndTime());
        data.setTimeLimit(gameLog.getTimeLimit());
        DataContainer.deskContainer.put(data.getId(),data);
        initData(null);
        lightControl(true);
    }

    public void closeDesk() {
        data.setStatus("1");
        data.setAmount(null);
        data.setIncome(null);
        data.setPlayer(null);
        data.setStartTime(null);
        data.setEndTime(null);
        data.setCartList(null);
        progressBar.setProgress(0);
        initData(5);
        lightControl(false);
        Integer two = 2;
        if(two.equals(data.getTimeLimit())){
           stopAnimate();
        }
        DataContainer.deskContainer.put(data.getId(),data);
    }

    public void stopAnimate() {
        if(null != timer){
            timer.cancel();
            timer = null;
        }
    }


    public void overtimeClose() {
        initData(null);
    }

    private void lightControl(boolean state) {
        Integer num = data.getDeskNo();
        String msg = null;
        if(state){
            msg = "A"+num.toString();
        }else{
            msg = "B"+num.toString();
        }
        serialManager.sendMsg(msg);
        logger.info("[发送信号]-:{}",msg);
    }

    public void refreshDeskData(){
        if(data != null){
            data =  clientService.getDeskById(data.getId());
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    DataContainer.deskContainer.put(data.getId(),data);
                    initData(null);
                }
            });
        }
    }

    private boolean flick = false;
    private int flickIndex = 0;

    public void flickerCart() {

        Timer timerP = new Timer();
        timerP.schedule(new TimerTask() {
            @Override
            public void run() {
                if(flick){
                    cartImgView.setImage(cartOpen);
                }else{
                    cartImgView.setImage(cartClose);
                }
                flick = !flick;
                flickIndex++;
                if(flickIndex >= 4){
                    flick = false;
                    flickIndex = 0;
                    timerP.cancel();
                }
            }
        },100,300);
    }
}
